﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Composition;
using System.Data;
using System.IdentityModel.Tokens.Jwt;
using System.Linq.Expressions;
using System.Runtime.Serialization.Formatters;
using System.Security.AccessControl;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Xml.Linq;
using ExchangeClient.Abstractions;
using ExchangeClient.Abstractions.Model;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using NETCore.Encrypt;
using NPOI.HSSF.Record.Chart;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using NPOI.XSSF.UserModel;
using SyncService.Abstractions.Events;
using SyncService.Abstractions.Services;
using SyncService.Core.Model;
using static Org.BouncyCastle.Bcpg.Attr.ImageAttrib;


namespace SyncService.Core.Services
{
    [Export(typeof(ISyncService))]
    [ExportMetadata(YdConstants.ID, "sample")]
    public class SampleService : PushDataMiddle
    {
        //密钥
        private static readonly string SecretKey = "dc41d891-9f1b-4aa2-a8df-fb00a186ded7}";//用guid生成的一个密钥
        private static readonly SymmetricSecurityKey SecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));
        private static readonly SigningCredentials SigningCredentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256);
        private static string Tokenstring = "";
        private IMemoryCache? _cache = null;
        private ILogger<SampleService> _logger = null;
        Dictionary<string, string> companyData = new Dictionary<string, string>();
        private Dictionary<string, string> centerData = new Dictionary<string, string>();
        private Dictionary<string, string> centerDatabyID = new Dictionary<string, string>();
        public SampleService() : base(YdConstants.YIDEA, "Esb", "")
        {
        }
        protected override void InitializeContext()
        {
            base.InitializeContext();
            _logger = Resolver.Resolve<ILogger<SampleService>>();
            _cache = Resolver.Resolve<IMemoryCache>();
        }
        public override void ExecuteCore()
        {
            Data = (AssetSyncEvent)State!;

            bool isNeedReadOrder = false;


            Process process = new Process();
            process.SerialNo = SerialNo.ToString();
            _logger.LogInformation("推esb流程中心：" + SerialNo);
            string employeeNo = "";
            //推送给esb创建流程
            JsonObject extraModel = new JsonObject();
            JsonObject model = new JsonObject();

            string code = SerialNo.Substring(0, 3);

            var condition = new JsonArray();
            condition.Add(new JsonObject()
            {
                ["field"] = "serialNo",
                ["type"] = "input",
                ["label"] = "流水号",
                ["opt"] = "Equal",
                ["val"] = SerialNo
            });

            model.Add("formCode", code);
            switch (code)
            {
                //报废
                case "CLN":
                    isNeedReadOrder = true;
                    SourceType = 48;
                    extraModel.Add("amount", GetExtendFieldValue("原值"));
                    extraModel.Add("netWorth", GetExtendFieldValue("净值"));
                    extraModel.Add("createByNo", GetEmployeeById().EmployeeNo);
                    extraModel.Add("assetTypeName1", GetTopAssetTypeById().Name);
                    extraModel.Add("assetTypeCode1", GetTopAssetTypeById().Code);
                    extraModel.Add("assetTypeName2", GetTopAssetTypeById(1).Name);
                    extraModel.Add("assetTypeCode2", GetTopAssetTypeById(1).Code);
                    extraModel.Add("companyCode", GetExtendFieldValue("公司代码"));

                    try
                    {
                        var Engineeringforms = UserDefines.First(x => x.Name == "字典管理-工程跳转地址");
                        var VformIds = UserDefines.First(x => x.Name == "报废自定义表单");
                        var EngineeringNo = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "工程处置单号");
                        var EngineeringAddress = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "工程处置单号地址");
                        var number = ExtendFields.First(x => x.ObjectType == 48 && x.Name == "数字");
                        if (int.TryParse(Data?.Data?[number.FieldId]?.ToString(), out int num))
                        {
                            if (num > 0)
                            {
                                var serNo = Data.Data[EngineeringNo.FieldId].ToString();
                                serNo = serNo.TrimStart('，', ',').TrimEnd('，', ',');
                                string[] serNoitems = serNo.Split('，', ',');
                                string newStrNos = string.Empty;
                                string urllists = string.Empty;
                                //生成工程单跳转地址
                                string jumpUrls = string.Empty;
                                string keys = string.Empty;
                                //获取系统字典预存url&&秘钥
                                var dicResults = YideaClient.GetDictionaryDetails(dicId: Guid.Parse(Engineeringforms.Id.ToString()), null).ToList();

                                if (dicResults != null)
                                {
                                    //工程地址
                                    jumpUrls = dicResults.Where(s => s.Comment.Contains("工程地址")).FirstOrDefault()!.Name;
                                    //秘钥
                                    keys = dicResults.Where(s => s.Comment.Contains("秘钥KEY")).FirstOrDefault()!.Name;

                                    if (serNoitems != null)
                                    {
                                        foreach (string item in serNoitems)
                                        {
                                            if (!string.IsNullOrWhiteSpace(item))  // 过滤空项
                                                newStrNos += item + ",";
                                        }
                                        newStrNos = newStrNos.TrimEnd(',', '，');

                                        var sign = EncryptProvider.Md5("YDYD" + newStrNos + keys);
                                        urllists = $"{jumpUrls}?sys=YDYD&data={newStrNos}&sign={sign}";
                                        var order = YideaClient.GetCustomizedFormDatas((Guid)Data.Data["FormId"], new QueryParam() { FilterString = JsonSerializer.Serialize(condition) }).FirstOrDefault();
                                        var datajson = JsonNode.Parse(order.Data["dataJson"].ToString());
                                        datajson[EngineeringAddress.FieldId] = urllists;
                                        var data2 = JsonSerializer.Serialize(datajson);
                                        UserDefinedForm userDefinedForm = new UserDefinedForm() { Id = Guid.Parse(order.Data["id"].ToString()), SerialNo = order.Data["serialNo"].ToString(), FormId = VformIds.Id, JsonData = data2 };
                                        var updateResponse = YideaClient.UpdateUserDefinedForm(userDefinedForm, null);
                                        _logger.LogInformation("修改结果" + updateResponse);
                                    }


                                }
                                else
                                {
                                    _logger.LogInformation("请求工程地址&秘钥失败");
                                }
                            }
                        }


                    }
                    catch (Exception)
                    {
                        _logger.LogInformation($"请求工程地址&秘钥失败");
                    }

                    break;
                //调拨
                case "TRA":
                    //发送流程前先检索数据是否合格
                    CheckOrderTRA(Data);
                    SourceType = 49;
                    var inCode = GetExtendFieldValue("调入公司码");
                    var outCode = GetExtendFieldValue("调出公司码");
                    extraModel.Add("outCompanyCode", outCode);
                    extraModel.Add("inCompanyCode", inCode);
                    if (outCode != inCode)
                    {
                        extraModel.Add("traType", 1);

                    }
                    else
                    {
                        extraModel.Add("traType", 0);
                    }
                    var rst = JsonSerializer.Deserialize<Manager>(GetExtendFieldValue("调入管理员"));
                    extraModel.Add("userNo", rst.code);


                    break;
                case "NTR":
                    model["formCode"] = "TRA";
                    SourceType = 60;
                    inCode = GetExtendFieldValue("调入公司码");
                    outCode = GetExtendFieldValue("调出公司码");
                    extraModel.Add("outCompanyCode", outCode);
                    extraModel.Add("inCompanyCode", inCode);
                    if (inCode == "")
                    {
                        extraModel.Add("traType", 0);
                    }
                    else
                    {
                        extraModel.Add("traType", 1);
                    }
                    rst = JsonSerializer.Deserialize<Manager>(GetExtendFieldValue("调入管理员"));
                    extraModel.Add("userNo", rst.code);
                    //extraModel.Add("assetType", GetTopAssetTypeById().Code);
                    //extraModel.Add("assetTypeName", GetTopAssetTypeById().Name);
                    #region 废弃
                    //string url = "https://www.bilibili.com/";
                    //var claims = new[]
                    //{
                    //    new Claim("url", url)
                    //};

                    //var token = new JwtSecurityToken(
                    //issuer: "1",//发送方
                    //audience: "2",//接收方    //这俩个发送方和接收方是生成token的时候传进去传1，2也可以但是对应的解析的时候的发送方和接收方也要写1，2
                    //claims: claims,
                    //expires: DateTime.UtcNow.AddHours(2),
                    //signingCredentials: SigningCredentials
                    //);
                    //Tokenstring = new JwtSecurityTokenHandler().WriteToken(token);
                    //var tokenstring = new JwtSecurityTokenHandler().WriteToken(token);
                    #endregion

                    var Engineeringform = UserDefines.First(x => x.Name == "字典管理-工程跳转地址");
                    var VformId = UserDefines.First(x => x.Name == "V测试资产调拨单");
                    var Engineering = ExtendFields.First(x => x.ObjectType == 60 && x.Name == "工程处置单号");
                    var EngineeringUrl = ExtendFields.First(x => x.ObjectType == 60 && x.Name == "工程处置单号地址");
                    var number1 = ExtendFields.First(x => x.ObjectType == 60 && x.Name == "数字1");
                    var number2 = ExtendFields.First(x => x.ObjectType == 60 && x.Name == "数字2");

                    //调拨单 数字1或者数字2大于0，处理工程处置单号和工程单号地址
                    if (int.TryParse(Data?.Data?[number1.FieldId]?.ToString(), out int num1) && int.TryParse(Data?.Data?[number2.FieldId]?.ToString(), out int num2))
                    {
                        if (num1 > 0 || num2 > 0)
                        {
                            var asd = Data.Data[Engineering.FieldId].ToString();
                            asd = asd.TrimStart('，', ',').TrimEnd('，', ',');
                            string[] items = asd.Split('，', ',');
                            string newStrNo = string.Empty;
                            string urllist = string.Empty;
                            //生成工程单跳转地址
                            string jumpUrl = string.Empty;
                            string key = string.Empty;
                            //获取系统字典预存url&&秘钥
                            var dicResult = YideaClient.GetDictionaryDetails(dicId: Guid.Parse(Engineeringform.Id.ToString()), null).ToList();
                            if (dicResult != null)
                            {
                                //工程地址
                                jumpUrl = dicResult.Where(s => s.Comment.Contains("工程地址")).FirstOrDefault()!.Name;
                                //秘钥
                                key = dicResult.Where(s => s.Comment.Contains("秘钥KEY")).FirstOrDefault()!.Name;
                                if (!string.IsNullOrEmpty(asd))
                                {
                                    foreach (string item in items)
                                    {
                                        if (!string.IsNullOrWhiteSpace(item))  // 过滤空项
                                            newStrNo += item + ",";
                                    }
                                    newStrNo = newStrNo.TrimEnd(',', '，');

                                    var sign = EncryptProvider.Md5("YDYD" + newStrNo + key);
                                    urllist = $"{jumpUrl}?sys=YDYD&data={newStrNo}&sign={sign}";
                                    var order = YideaClient.GetCustomizedFormDatas((Guid)Data.Data["FormId"], new QueryParam() { FilterString = JsonSerializer.Serialize(condition) }).FirstOrDefault();
                                    var datajson = JsonNode.Parse(order.Data["dataJson"].ToString());
                                    datajson[EngineeringUrl.FieldId] = urllist;
                                    var data2 = JsonSerializer.Serialize(datajson);
                                    UserDefinedForm userDefinedForm = new UserDefinedForm() { Id = Guid.Parse(order.Data["id"].ToString()), SerialNo = order.Data["serialNo"].ToString(), FormId = VformId.Id, JsonData = data2 };
                                    var updateResponse = YideaClient.UpdateUserDefinedForm(userDefinedForm, null);
                                    _logger.LogInformation("修改结果" + updateResponse);
                                }
                            }
                            else
                            {
                                _logger.LogInformation("请求工程地址&秘钥失败");
                            }

                        }
                    }



                    break;
                //盘点单
                case "AIN":
                    SourceType = 51;
                    List<User> users = FromClient.GetUsers(new QueryParam()
                    {
                        FilterString = "id=" + CreatedById
                    }).ToList();
                    if (users.Count > 0)
                    {
                        extraModel.Add("createByNo", users[0].EmployeeNo);
                        employeeNo = users[0].EmployeeNo;
                    }
                    else
                    {
                        extraModel.Add("createByNo", "");
                    }

                    QueryParam queryParam = new QueryParam();
                    queryParam.Keyword = SerialNo;
                    queryParam.FilterString = "inventoryStateIn=1,0,2";
                    List<AssetInventory> assets = FromClient.GetAssetInventoryItems(queryParam).ToList();
                    string assetCompanyCode = "";
                    var Field = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "公司代码");
                    if (assets.Count > 0)
                    {
                        assetCompanyCode = assets[0].ExtensionFields.Where(e => e.Model == Field.FieldId).Select(e => e.Value).First();
                    }
                    extraModel.Add("companyCode", assetCompanyCode);
                    break;
                //发票登记单
                case "IEF":
                    SourceType = 50;
                    var companyCode = GetExtendFieldValue("公司代码");
                    extraModel.Add("companyCode", companyCode);
                    //extraModel.Add("assetType", GetTopAssetTypeById().Code);
                    //extraModel.Add("assetTypeName", GetTopAssetTypeById().Name);
                    break;
                //入库单
                case "AIS":
                    SourceType = 55;
                    var companyCodeField = ExtendFields.Where(x => x.Name == "CompanyCode" && x.ObjectType == 0).First();
                    var flowPush = GetExtendFieldValue("审批分支判断");
                    if (flowPush == "1" || flowPush == "3")
                    {
                        return;
                    }
                    extraModel.Add("companyCode", companyCodeField.FieldId);
                    employeeNo = Data.Data["operator"]["employeeno"]?.ToString();
                    var creatorId = Data.Data["creator"] == null ? "" : Data.Data["creator"]["value"].ToString();
                    _logger.LogInformation("盘点单创建人：" + creatorId);
                    var creatorNo = "";
                    if (!string.IsNullOrEmpty(creatorId))
                    {
                        List<User> ais_users = YideaClient.GetUsers(new QueryParam() { FilterString = "id=" + creatorId }).ToList();
                        if (ais_users.Count > 0)
                        {
                            _logger.LogInformation("查到了管理员关联的员工编号");
                            employeeNo = ais_users[0].EmployeeNo;
                        }
                    }

                    break;
                case "ZER"://0元列管入库单
                    SourceType = 57;
                    var companyField = ExtendFields.Where(x => x.Name == "公司代码" && x.ObjectType == 57).First();
                    extraModel.Add("companyCode", Data.Data[companyField.FieldId]?.ToString());
                    break;
                case "MTR":
                    var outCompanyCodeField = ExtendFields.First(e => e.Name == "调出公司代码" && e.ObjectType == 59);
                    var inCompanyCodeField = ExtendFields.First(e => e.Name == "调入公司代码" && e.ObjectType == 59);
                    var inManagerNoField = ExtendFields.First(e => e.Name == "调入管理员编号" && e.ObjectType == 59);
                    SourceType = 59;
                    extraModel.Add("outCompanyCode", Data.Data[outCompanyCodeField.FieldId]?.ToString());
                    extraModel.Add("inCompanyCode", Data.Data[inCompanyCodeField.FieldId]?.ToString());
                    extraModel.Add("userNo", Data.Data[inManagerNoField.FieldId]?.ToString());

                    break;

            }
            if (string.IsNullOrEmpty(employeeNo))
            {
                employeeNo = GetEmployeeById().EmployeeNo;
            }
            process.UserId = employeeNo;


            var pendingApproval = (JsonObject)Data.Data!["ApprovalInformation"]!;
            var pendingApprovalArray = (JsonArray)pendingApproval?["PendingApprovalRecipients"];
            JsonNode pendingApprovalUrl;
            if (pendingApprovalArray == null)
            {
                pendingApprovalUrl = "";
            }
            else
            {
                pendingApprovalUrl = pendingApprovalArray.Count == 0 ? "" : pendingApprovalArray[0]!["PendingApprovalUrl"];
            }

            model.Add("systemAppUrl", pendingApprovalUrl?.ToString());
            model.Add("extraModel", extraModel);
            process.ExtraData = model;
            if (SourceType == 51 && extraModel["companyCode"] != null && string.IsNullOrEmpty(extraModel["companyCode"].ToString()))
            {
                _logger.LogInformation("盘点单公司编码为空，不推送esb");
            }
            else
            {
                if (isNeedReadOrder)
                {
                    var form = UserDefines.Where(x => x.Name == FormName[SourceType]).FirstOrDefault();
                    Thread.Sleep(60000);
                    var searchArray = new JsonArray();
                    searchArray.Add(new JsonObject()
                    {
                        ["field"] = "serialNo",
                        ["type"] = "input",
                        ["label"] = "流水号",
                        ["opt"] = "In",
                        ["val"] = SerialNo
                    });
                    var searchString = JsonSerializer.Serialize(searchArray);
                    var formData = YideaClient.GetCustomizedFormDatas(form.Id, new QueryParam() { FilterString = searchString }).FirstOrDefault();
                    if (formData == null)
                    {
                        _logger.LogInformation(SerialNo + "调用接口查询失败。不推送Esb");
                        return;
                    }
                }


                JsonObject response = ToClient.PushProcess(process);


                UpdateMainPushResponse(response);
                //插入记录表
                int state = response["code"]!.ToString() == "000000" ? 0 : -1;
                string result = response["result"] == null ? "" : response["result"].ToString();
                AddPushRecord(state, result);
            }

        }
        /// <summary>
        /// 发送流程前检索条件
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        private bool CheckMTR(AssetSyncEvent Data)
        {

            return false;
        }

        private void CheckOrderTRA(AssetSyncEvent Data)
        {

            Dictionary<string, int> barcodeInRow = new Dictionary<string, int>();
            List<Asset> assets = new List<Asset>();
            DataTable dataTable = new DataTable();
            DataTable errorAsset = new DataTable();
            var company = UserDefines.First(x => x.Name == "公司主数据");
            var center = UserDefines.First(x => x.Name == "成本中心");
            var serialNo = Data.Data["SerialNo"].ToString();
            var fileUploadField = ExtendFields.Where(e => e.ObjectType == 59 && e.Name == "附件").FirstOrDefault();
            var fileDemain = ExtendFields.Where(e => e.ObjectType == 0 && e.Name == "附件域名").FirstOrDefault();
            var centerMasterCodeField = ExtendFields.First(x => x.ObjectType == 52 && x.Name == "成本中心");
            var centerMasterNameField = ExtendFields.First(x => x.ObjectType == 52 && x.Name == "成本中心名称");
            var centerMasterCompanyCodeField = ExtendFields.First(x => x.ObjectType == 52 && x.Name == "公司代码");
            var companyMasterCodeField = ExtendFields.First(x => x.ObjectType == 51 && x.Name == "公司代码");
            var companyMasterNameField = ExtendFields.First(x => x.ObjectType == 51 && x.Name == "公司名称");
            var isGuoZhangField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name == "是否过账");
            var companyCodeField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("公司代码"));
            var assetComapnyField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("公司名称"));
            var centerCodeField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("成本中心码"));
            var centerNameField = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "成本中心名");
            var assetCenterField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name.Equals("成本中心名称"));
            var shopCodeField = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "店铺代码");
            var shopNameField = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "店铺名称");
            var addressField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name == "存放地");
            var outCompanyCodeField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name == "调出公司代码");
            var inCompanyCodeField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name == "调入公司代码");
            var transferDateField = ExtendFields.FirstOrDefault(x => x.ObjectType == 0 && x.Name == "调拨时间");
            var inCompanyCode = ExtendFields.FirstOrDefault(x => x.ObjectType == 62 && x.Name == "调入公司代码");

            var filePath = fileDemain.FieldId + Data.Data[fileUploadField.FieldId]?[0]["url"].ToString();


            dataTable = Common.Excel.ReadExcel.ReadNetWorkFile(filePath);


            if (dataTable == null)
            {
                _logger.LogInformation("批量调拨单" + serialNo + "获取数据失败");
                return;
            }

            DataColumn workCol = dataTable.Columns.Add("失败原因", typeof(string));
            errorAsset = dataTable.Copy();
            errorAsset.Rows.Clear();

            List<District> districts = YideaClient.GetDistricts(null).ToList();

            var companyList = YideaClient.GetCustomizedFormDatas(formId: company.Id, new QueryParam() { }).ToList();

            ConvertCompanyToDic(companyList);

            var centerlist = YideaClient.GetCustomizedFormDatas(formId: center.Id, new QueryParam() { }).ToList();

            ConvertCenterToDic(centerlist);

            List<Department> departmentList = YideaClient.GetDepartments(null).ToList();
            // List<Employee> employeeList = YideaClient.GetEmployees(null).ToList();

            List<string> barcodeList = new List<string>();
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                var row = dataTable.Rows[i];
                var barcode = row[0].ToString();
                barcodeList.Add(barcode);
            }


            #region    取所有资产
            var page = 0;
            var perPage = 100;
            var getAssetsBarcodes = barcodeList.Select(e => e).Skip(page * perPage).Take(perPage).ToList();
            while (getAssetsBarcodes.Any())
            {
                var yideaExistingAssetsRes = YideaClient.GetAssets(new QueryParam
                {
                    FilterString = $"orderby=-id&requireHierarchies=1&filterByPermission=1&barcodeIn={string.Join(",", getAssetsBarcodes)}"
                });
                var list = yideaExistingAssetsRes.ToList();
                assets.AddRange(list);
                page++;
                getAssetsBarcodes = barcodeList.Select(e => e).Skip(page * perPage).Take(perPage).ToList();

            }
            #endregion


            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                var row = dataTable.Rows[i];
                try
                {

                    var barcode = row[0].ToString();

                    if (barcodeInRow.ContainsKey(barcode))
                    {
                        continue;
                    }
                    else
                    {
                        barcodeInRow.Add(barcode, i);
                    }
                    //  1. 校验资产编码是否存在于资产台账
                    var asset = assets.Where(e => e.Barcode == barcode).FirstOrDefault();
                    if (asset == null)
                    {
                        row[4] = "该资产在台账中不存在";
                        errorAsset.ImportRow(row);
                        continue;
                    }
                    //  2. 校验资产是否过账
                    var assetJson = JsonNode.Parse(asset.DataJson).AsObject();
                    if (assetJson[isGuoZhangField.FieldId].ToString() != "是")
                    {
                        row[4] = "该资产是否过账为否，不允许调拨";
                        errorAsset.ImportRow(row);

                        continue;
                    }
                    //  3. 校验资产是否占用
                    if (asset.IncludedInBill > 0)
                    {
                        row[4] = "该资产被占用，不允许调拨";
                        errorAsset.ImportRow(row);

                        continue;
                    }
                    //  4. 校验导入资产区域是否存在
                    var distrinct = row[1].ToString();
                    if (!string.IsNullOrEmpty(distrinct))
                    {
                        var districtID = districts.Where(e => e.Name == distrinct).FirstOrDefault();
                        if (districtID == null)
                        {
                            row[4] = "该资产区域填写错误";
                            errorAsset.ImportRow(row);
                            continue;
                        }

                    }

                    // 5.1、校验原始数据是否为空。(调入成本中心不能为空)
                    var centerCode = row[2].ToString();
                    _logger.LogInformation(serialNo + "::" + centerCode);
                    if (string.IsNullOrEmpty(centerCode))
                    {
                        string errorMessage = "该资产成本中心填写错误：调入成本中心不能为空";
                        row[4] = errorMessage;
                        errorAsset.ImportRow(row);
                        _logger.LogInformation(serialNo + ":31:" + errorMessage);
                        continue;
                    }
                    // 5.2、校验成本中心是否存在。(调入成本中心不存在)
                    var centerfilter = centerData.Where(s => s.Key == centerCode).FirstOrDefault();
                    if (centerfilter.Key == null)
                    {
                        row[4] = "调入成本中心不存在";
                        errorAsset.ImportRow(row);
                        continue;
                    }
                    // 5.3、校验成本中心所属公司是否与调入公司一致(调入成本中心公司与调入公司不一致)
                    JsonObject? selectCompany = JsonSerializer.Deserialize<JsonObject>(
                        JsonSerializer.Deserialize<JsonObject>(centerfilter.Value)?["dataJson"]?.ToString() ?? ""
                        );
                    //  成本中心公司代码
                    var centerCompanyCode = selectCompany[centerMasterCompanyCodeField.FieldId]?.ToString();
                    //  批量调拨单调入公司代码
                    var bulktrInCoCode = Data.Data[inCompanyCode.FieldId]?.ToString();
                    if (centerCompanyCode != bulktrInCoCode)
                    {
                        row[4] = "调入成本中心公司与调入公司不一致";
                        errorAsset.ImportRow(row);
                        continue;
                    }

                }
                catch (Exception ex)
                {
                    _logger.LogInformation(serialNo + "发生异常：" + ex);
                    row[4] = "发生异常：" + ex.ToString();
                    errorAsset.ImportRow(row);
                    continue;

                }
            }
            string fullFile = "";
            if (errorAsset.Rows.Count > 0)
            {
                var filepath = ExportToString(errorAsset);
                var domainNameField = ExtendFields.First(e => e.Name == "域名" && e.ObjectType == 0);
                fullFile = filepath == "" ? "" : domainNameField.FieldId + filepath;
                WriteToForm(Data.Data["SerialNo"]!.ToString(), fullFile);
            }
            companyData.Clear();
            centerData.Clear();
            centerDatabyID.Clear();
            assets.Clear();
            dataTable.Clear();
            errorAsset.Clear();
            districts.Clear();
            companyList.Clear();
            centerlist.Clear();
            departmentList.Clear();

        }
        private void WriteToForm(string serialNo, string filePath)
        {
            _logger.LogInformation("批量调拨回写：" + serialNo);
            var form = UserDefines.Where(e => e.Name == "新资产批量调拨单").FirstOrDefault();
            var errorLinkField = ExtendFields.Where(e => e.Name == "错误数据链接" && e.ObjectType == 62).FirstOrDefault();
            var condition = new JsonArray();
            condition.Add(new JsonObject()
            {
                ["field"] = "serialNo",
                ["type"] = "input",
                ["label"] = "流水号",
                ["opt"] = "Equal",
                ["val"] = serialNo
            });


            CustomizedFormData order = YideaClient.GetCustomizedFormDatas(form.Id, new QueryParam() { FilterString = JsonSerializer.Serialize(condition) }).FirstOrDefault();
            if (order != null)
            {

                CustomizedFormData updateCustomer = new CustomizedFormData();
                updateCustomer.FormId = form.Id;
                updateCustomer.WebhookPush = false;
                updateCustomer.SerialNo = order.SerialNo;
                JsonObject upField = new JsonObject();
                upField[errorLinkField.FieldId] = new JsonObject
                {
                    ["value"] = filePath
                };
                updateCustomer.Data = upField;
                var updateResponse1 = YideaClient.UpdateCustomizedFormData(updateCustomer, null);
                _logger.LogInformation("新资产批量调拨流程流转：" + serialNo + "上传错误结果：" + updateResponse1 + "发送流程中心失败，原因：excel内有错误数据");
            }
        }
        private bool IsPush(string assetTypeCode)
        {
            string NotPushSap = ExtendFields.First(x => x.ObjectType == 0 && x.Name == "NotPushAssetType").FieldId;
            var code = GetTopAssetTypeCode(assetTypeCode);
            _logger.LogInformation("推送sap资产编码是否推送：" + NotPushSap.Contains("," + code + ","));
            return NotPushSap.Contains("," + code + ",");
        }
        private string GetTopAssetTypeCode(string assetTypeCode)
        {
            List<AssetType> assetTypeList = GetAssetTypeFromCache();
            var assetType = assetTypeList.Where(e => e.Code == assetTypeCode).FirstOrDefault();
            var hierarchyId = assetType.Hierarchy.Split('|')[0];
            int topAssetTypeId = 0;
            int.TryParse(hierarchyId, out topAssetTypeId);
            var topAssetType = assetTypeList.Where(e => e.Id == topAssetTypeId).FirstOrDefault();
            if (topAssetType != null)
            {
                return topAssetType.Code;
            }
            else
            {
                return assetTypeCode;
            }
        }
        private List<AssetType> GetAssetTypeFromCache()
        {
            _cache.TryGetValue("AssetType", out var assetValue);
            List<AssetType> assetTypeList = new List<AssetType>();
            if (assetValue != null)
            {
                assetTypeList = ((IEnumerable<dynamic>)assetValue).Select(item => new AssetType
                {
                    Id = item.Id,
                    Name = item.Name,
                    Hierarchy = item.Hierarchy,
                    Code = item.Code
                }).ToList();
            }
            else
            {
                assetTypeList = FromClient.GetAssetTypes(null).ToList();
                _cache.Set("AssetType", assetTypeList, DateTime.Now.AddMinutes(5));
            }
            return assetTypeList;
        }
        private void ConvertCompanyToDic(List<CustomizedFormData> datas)
        {

            var companyMasterCodeField = ExtendFields.First(x => x.ObjectType == 51 && x.Name == "公司代码");
            foreach (var data in datas)
            {
                var custmerData = JsonSerializer.Serialize(data.Data);
                JsonObject companyDataJson = JsonNode.Parse(data.Data["dataJson"].ToString()).AsObject();
                var key = companyDataJson[companyMasterCodeField.FieldId].ToString();
                if (companyData.ContainsKey(key))
                {
                    continue;
                }
                else
                {
                    companyData.Add(key, custmerData);
                }
            }

        }
        private void ConvertCenterToDic(List<CustomizedFormData> datas)
        {

            var centerMasterNameField = ExtendFields.First(x => x.ObjectType == 52 && x.Name == "成本中心名称");
            var centerMasterCodeField = ExtendFields.First(x => x.ObjectType == 52 && x.Name == "成本中心");
            foreach (var data in datas)
            {
                var custmerData = JsonSerializer.Serialize(data.Data);
                JsonObject companyDataJson = JsonNode.Parse(data.Data["dataJson"].ToString()).AsObject();
                var key = companyDataJson[centerMasterCodeField.FieldId].ToString();
                if (centerData.ContainsKey(key))
                {
                    continue;
                }
                else
                {
                    centerData.Add(key, custmerData);
                }
                //var code = companyDataJson[centerMasterCodeField.FieldId].ToString();
                if (centerDatabyID.ContainsKey(key))
                {
                    continue;
                }
                else
                {
                    centerDatabyID.Add(key, data.Id.ToString());
                }

            }
        }
        public string ExportToString(DataTable dataTable)
        {
            _logger.LogInformation("开始导出资产回写情况统计excel~");
            var template = Path.Combine(SyncService.Common.Constants.WebRootPath, "Templates", "批量调拨回写统计.xlsx");
            var fileName = DateTime.Now.ToString("yyyyMMddHHmmssffff");
            var target = Path.Combine(SyncService.Common.Constants.WebRootPath, "temp", $"{fileName}批量调拨回写统计.xlsx");
            string directory = Path.GetDirectoryName(target);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            System.IO.File.Copy(template, target);
            FileStream file = new FileStream(target, FileMode.Open, FileAccess.Read);
            var workbook = new XSSFWorkbook(file);
            var sheet = workbook.GetSheet("批量调拨回写统计");
            int rowIndex = sheet.LastRowNum;

            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                var row = dataTable.Rows[i];
                XSSFRow dataRow = (XSSFRow)sheet.CreateRow(rowIndex);
                dataRow.CreateCell(0).SetCellValue(row[0].ToString());
                dataRow.CreateCell(1).SetCellValue(row[1].ToString());
                dataRow.CreateCell(2).SetCellValue(row[2].ToString());
                dataRow.CreateCell(3).SetCellValue(row[3].ToString());

                dataRow.CreateCell(4).SetCellValue(row[4].ToString());

                ++rowIndex;
            }

            using (var stream = new FileStream(target, FileMode.Create, FileAccess.Write))
            {
                workbook.Write(stream);
            }
            _logger.LogInformation("生成excel");
            _logger.LogInformation(target);
            //string base64 = FileToBase64String.FileToBase64(target);
            return "/temp/" + fileName + "批量调拨回写统计.xlsx";
        }

    }
}
